﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog;
using NLog.Config;
using NLog.Targets;
using FB.Enums;


namespace FB.Services
{
    public class LoggingService
    {

        public LoggingService()
        {
        }


        public LoggingConfiguration GetLoggingConfig(string connectionStringNameForAppLogger, string connectionStringNameForMemberLogger = null)
        {
            var config = new NLog.Config.LoggingConfiguration();

            #region Logging Targets

            if (!string.IsNullOrEmpty(connectionStringNameForMemberLogger))
            {
                var MembershipDBTarget = new DatabaseTarget();
                MembershipDBTarget.Name = "MembershipLogTarget";
                MembershipDBTarget.DBProvider = "mssql";
                MembershipDBTarget.ConnectionStringName = connectionStringNameForMemberLogger;
                MembershipDBTarget.CommandText = "INSERT INTO [dbo].[MembershipLogs] ([TimeStamp],[Level],[Host],[RemoteAddr],[Logger],[Url],[Message]) VALUES (@timestamp,@level,@host,@remote_addr,@logger,@url,@message); ";

                MembershipDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@timestamp", Layout = "${date}" });
                MembershipDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@level", Layout = "${level:uppercase=true}" });
                MembershipDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@host", Layout = "${machinename}" });
                MembershipDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@remote_addr", Layout = "${aspnet-request:serverVariable=remote_host}" });
                MembershipDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@logger", Layout = "${logger}" });
                MembershipDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@url", Layout = "${aspnet-request:serverVariable=path_info} ${aspnet-request:serverVariable=query_string}" });
                MembershipDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@message", Layout = "${message}" });

                config.AddTarget("MembershipLogTarget", MembershipDBTarget);
                config.LoggingRules.Add(new NLog.Config.LoggingRule(typeof(FB.Log.AspnetAccessLogger).FullName, NLog.LogLevel.Info, MembershipDBTarget) { Final = true });
            }

            var fileTarget = new FileTarget();
            fileTarget.Name = "FileLogTarget";
            fileTarget.FileName = "${basedir}/logs/${shortdate}.log";
            fileTarget.Layout = "${date}${newline}"
                + "level: ${level:uppercase=true}${newline}"
                + "machinename: ${machinename}${newline}"
                + "remote_addr: ${aspnet-request:serverVariable=remote_host}${newline}"
                + "logger: ${logger}${newline}"
                + "source: ${callsite:className=true:fileName=false:includeSourcePath=false:methodName=true}${newline}"
                + "url: ${aspnet-request:serverVariable=path_info} ${aspnet-request:serverVariable=query_string}${newline}"
                + "message: ${message}${newline}"
                + "exception: ${exception:format=tostring}${newline}"
                + "------------------------------------------";

            config.AddTarget("FileLogTarget", fileTarget);
            config.LoggingRules.Add(new NLog.Config.LoggingRule("*", NLog.LogLevel.Debug, fileTarget));

      
            var AppDBTarget = new DatabaseTarget();
            AppDBTarget.Name = "ApplicationLogTarget";
            AppDBTarget.DBProvider = "mssql";
            AppDBTarget.ConnectionStringName = connectionStringNameForAppLogger;
            AppDBTarget.CommandText = "INSERT INTO dbo.Logs ([TimeStamp],[Level],[Host],[RemoteAddr],[Logger],[Source],[Url],[Message],[Exception]) VALUES (@timestamp,@level,@host,@remote_addr,@logger,@source,@url,@message,@exception); ";

            AppDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@timestamp", Layout = "${date}" });
            AppDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@level", Layout = "${level:uppercase=true}" });
            AppDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@host",  Layout = "${machinename}"});
            AppDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@remote_addr",  Layout = "${aspnet-request:serverVariable=remote_host}"});
            AppDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@logger", Layout = "${logger}"});
            AppDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@source", Layout = "${callsite:className=true:fileName=false:includeSourcePath=false:methodName=true}"});
            AppDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@url", Layout = "${aspnet-request:serverVariable=path_info} ${aspnet-request:serverVariable=query_string}" });
            AppDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@message", Layout = "${message}" });
            AppDBTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@exception", Layout = "${exception:format=tostring}" });

            config.AddTarget("ApplicationLogTarget", AppDBTarget);
            config.LoggingRules.Add(new NLog.Config.LoggingRule("*", NLog.LogLevel.Debug, AppDBTarget));
                        
            #endregion

            
            
            return config;
        }



        public void LogAccess(string Username, AccessStatus Status, string FurtherInfo = null)
        {
            var logger = GetAccessLogger();
            if (!string.IsNullOrEmpty(FurtherInfo))
            {
                logger.Info("AppsName:{0} | Username:{1} | Status:{2} | Detail:{3}", FB.Helpers.AppSettingsBase.AppKey.ToString(), Username, Status.ToString().Replace("_", " "), FurtherInfo);
            }
            else
            {
                logger.Info("AppsName:{0} | Username:{1} | Status:{2}", FB.Helpers.AppSettingsBase.AppKey.ToString(), Username, Status.ToString().Replace("_", " "));
            }
        }


        public Logger GetAccessLogger()
        {
            return NLog.LogManager.GetLogger(typeof(FB.Log.AspnetAccessLogger).FullName);
        }

    }
}
